/*!
 * jQuery blockUI plugin
 * Version 2.42 (11-MAY-2012)
 * @requires jQuery v1.2.3 or later
 *
 * Examples at: http://malsup.com/jquery/block/
 * Copyright (c) 2007-2010 M. Alsup
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 * Thanks to Amir-Hossein Sobhi for some excellent contributions!
 */

;
(function() {

	function setup($) {
		if (/1\.(0|1|2)\.(0|1|2)/.test($.fn.jquery) || /^1.1/.test($.fn.jquery)) {
			alert('blockUI requires jQuery v1.2.3 or later!  You are using v'
					+ $.fn.jquery);
			return;
		}

		$.fn._fadeIn = $.fn.fadeIn;

		var noOp = function() {
		};

		// this bit is to ensure we don't call setExpression when we shouldn't
		// (with extra muscle to handle
		// retarded userAgent strings on Vista)
		var mode = document.documentMode || 0;
		var setExpr = $.browser.msie
				&& (($.browser.version < 8 && !mode) || mode < 8);
		var ie6 = $.browser.msie && /MSIE 6.0/.test(navigator.userAgent)
				&& !mode;

		// global $ methods for blocking/unblocking the entire page
		$.blockUI = function(opts) {
			install(window, opts);
		};
		$.unblockUI = function(opts) {
			remove(window, opts);
		};

		// convenience method for quick growl-like notifications
		// (http://www.google.com/search?q=growl)
		$.growlUI = function(title, message, timeout, onClose) {
			var $m = $('<div class="growlUI"></div>');
			if (title)
				$m.append('<h1>' + title + '</h1>');
			if (message)
				$m.append('<h2>' + message + '</h2>');
			if (timeout == undefined)
				timeout = 3000;
			$.blockUI({
				message : $m,
				fadeIn : 700,
				fadeOut : 1000,
				centerY : false,
				timeout : timeout,
				showOverlay : false,
				onUnblock : onClose,
				css : $.blockUI.defaults.growlCSS
			});
		};

		// plugin method for blocking element content
		$.fn.block = function(opts) {
			var fullOpts = $.extend({}, $.blockUI.defaults, opts || {});
			this.each(function() {
				var $el = $(this);
				if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked'))
					return;
				$el.unblock({
					fadeOut : 0
				});
			});

			return this.each(function() {
				if ($.css(this, 'position') == 'static')
					this.style.position = 'relative';
				if ($.browser.msie)
					this.style.zoom = 1; // force 'hasLayout'
				install(this, opts);
			});
		};

		// plugin method for unblocking element content
		$.fn.unblock = function(opts) {
			return this.each(function() {
				remove(this, opts);
			});
		};

		$.blockUI.version = 2.42; // 2nd generation blocking at no extra cost!

		// override these in your code to change the default behavior and style
		$.blockUI.defaults = {
			// message displayed when blocking (use null for no message)
			message : '<h1>Please wait...</h1>',

			title : null, // title string; only used when theme == true
			draggable : true, // only used when theme == true (requires
								// jquery-ui.js to be loaded)

			theme : false, // set to true to use with jQuery UI themes

			// styles for the message when blocking; if you wish to disable
			// these and use an external stylesheet then do this in your code:
			// $.blockUI.defaults.css = {};
			css : {
				padding : 0,
				margin : 0,
				width : '30%',
				top : '40%',
				left : '35%',
				textAlign : 'center',
				color : '#000',
				border : '3px solid #aaa',
				backgroundColor : '#fff',
				cursor : 'wait'
			},

			// minimal style set used when themes are used
			themedCSS : {
				width : '30%',
				top : '40%',
				left : '35%'
			},

			// styles for the overlay
			overlayCSS : {
				backgroundColor : '#000',
				opacity : 0.6,
				cursor : 'wait'
			},

			// styles applied when using $.growlUI
			growlCSS : {
				width : '350px',
				top : '10px',
				left : '',
				right : '10px',
				border : 'none',
				padding : '5px',
				opacity : 0.6,
				cursor : 'default',
				color : '#fff',
				backgroundColor : '#000',
				'-webkit-border-radius' : '10px',
				'-moz-border-radius' : '10px',
				'border-radius' : '10px'
			},

			// IE issues: 'about:blank' fails on HTTPS and javascript:false is
			// s-l-o-w
			// (hat tip to Jorge H. N. de Vasconcelos)
			iframeSrc : /^https/i.test(window.location.href || '') ? 'javascript:false'
					: 'about:blank',

			// force usage of iframe in non-IE browsers (handy for blocking
			// applets)
			forceIframe : false,

			// z-index for the blocking overlay
			baseZ : 1000,

			// set these to true to have the message automatically centered
			centerX : true, // <-- only effects element blocking (page block
							// controlled via css above)
			centerY : true,

			// allow body element to be stetched in ie6; this makes blocking
			// look better
			// on "short" pages. disable if you wish to prevent changes to the
			// body height
			allowBodyStretch : true,

			// enable if you want key and mouse events to be disabled for
			// content that is blocked
			bindEvents : true,

			// be default blockUI will supress tab navigation from leaving
			// blocking content
			// (if bindEvents is true)
			constrainTabKey : true,

			// fadeIn time in millis; set to 0 to disable fadeIn on block
			fadeIn : 200,

			// fadeOut time in millis; set to 0 to disable fadeOut on unblock
			fadeOut : 400,

			// time in millis to wait before auto-unblocking; set to 0 to
			// disable auto-unblock
			timeout : 0,

			// disable if you don't want to show the overlay
			showOverlay : true,

			// if true, focus will be placed in the first available input field
			// when
			// page blocking
			focusInput : true,

			// suppresses the use of overlay styles on FF/Linux (due to
			// performance issues with opacity)
			applyPlatformOpacityRules : true,

			// callback method invoked when fadeIn has completed and blocking
			// message is visible
			onBlock : null,

			// callback method invoked when unblocking has completed; the
			// callback is
			// passed the element that has been unblocked (which is the window
			// object for page
			// blocks) and the options that were passed to the unblock call:
			// onUnblock(element, options)
			onUnblock : null,

			// don't ask; if you really must know:
			// http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493
			quirksmodeOffsetHack : 4,

			// class name of the message block
			blockMsgClass : 'blockMsg',

			// if it is already blocked, then ignore it (don't unblock and
			// reblock)
			ignoreIfBlocked : false
		};

		// private data and functions follow...

		var pageBlock = null;
		var pageBlockEls = [];

		function install(el, opts) {
			var css, themedCSS;
			var full = (el == window);
			var msg = (opts && opts.message !== undefined ? opts.message
					: undefined);
			opts = $.extend({}, $.blockUI.defaults, opts || {});

			if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked'))
				return;

			opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS,
					opts.overlayCSS || {});
			css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
			themedCSS = $.extend({}, $.blockUI.defaults.themedCSS,
					opts.themedCSS || {});
			msg = msg === undefined ? opts.message : msg;

			// remove the current block (if there is one)
			if (full && pageBlock)
				remove(window, {
					fadeOut : 0
				});

			// if an existing element is being used as the blocking content then
			// we capture
			// its current place in the DOM (and current display style) so we
			// can restore
			// it when we unblock
			if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {
				var node = msg.jquery ? msg[0] : msg;
				var data = {};
				$(el).data('blockUI.history', data);
				data.el = node;
				data.parent = node.parentNode;
				data.display = node.style.display;
				data.position = node.style.position;
				if (data.parent)
					data.parent.removeChild(node);
			}

			$(el).data('blockUI.onUnblock', opts.onUnblock);
			var z = opts.baseZ;

			// blockUI uses 3 layers for blocking, for simplicity they are all
			// used on every platform;
			// layer1 is the iframe layer which is used to supress bleed through
			// of underlying content
			// layer2 is the overlay layer which has opacity and a wait cursor
			// (by default)
			// layer3 is the message content that is displayed while blocking

			var lyr1 = ($.browser.msie || opts.forceIframe) ? $('<iframe class="blockUI" style="z-index:'
					+ (z++)
					+ ';display:none;border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="'
					+ opts.iframeSrc + '"></iframe>')
					: $('<div class="blockUI" style="display:none"></div>');

			var lyr2 = opts.theme ? $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'
					+ (z++) + ';display:none"></div>')
					: $('<div class="blockUI blockOverlay" style="z-index:'
							+ (z++)
							+ ';display:none;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>');

			var lyr3, s;
			if (opts.theme && full) {
				s = '<div class="blockUI '
						+ opts.blockMsgClass
						+ ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'
						+ (z + 10)
						+ ';display:none;position:fixed">'
						+ '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'
						+ (opts.title || '&nbsp;')
						+ '</div>'
						+ '<div class="ui-widget-content ui-dialog-content"></div>'
						+ '</div>';
			} else if (opts.theme) {
				s = '<div class="blockUI '
						+ opts.blockMsgClass
						+ ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'
						+ (z + 10)
						+ ';display:none;position:absolute">'
						+ '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'
						+ (opts.title || '&nbsp;')
						+ '</div>'
						+ '<div class="ui-widget-content ui-dialog-content"></div>'
						+ '</div>';
			} else if (full) {
				s = '<div class="blockUI ' + opts.blockMsgClass
						+ ' blockPage" style="z-index:' + (z + 10)
						+ ';display:none;position:fixed"></div>';
			} else {
				s = '<div class="blockUI ' + opts.blockMsgClass
						+ ' blockElement" style="z-index:' + (z + 10)
						+ ';display:none;position:absolute"></div>';
			}
			lyr3 = $(s);

			// if we have a message, style it
			if (msg) {
				if (opts.theme) {
					lyr3.css(themedCSS);
					lyr3.addClass('ui-widget-content');
				} else
					lyr3.css(css);
			}

			// style the overlay
			if (!opts.theme
					&& (!opts.applyPlatformOpacityRules || !($.browser.mozilla && /Linux/
							.test(navigator.platform))))
				lyr2.css(opts.overlayCSS);
			lyr2.css('position', full ? 'fixed' : 'absolute');

			// make iframe layer transparent in IE
			if ($.browser.msie || opts.forceIframe)
				lyr1.css('opacity', 0.0);

			// $([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
			var layers = [ lyr1, lyr2, lyr3 ], $par = full ? $('body') : $(el);
			$.each(layers, function() {
				this.appendTo($par);
			});

			if (opts.theme && opts.draggable && $.fn.draggable) {
				lyr3.draggable({
					handle : '.ui-dialog-titlebar',
					cancel : 'li'
				});
			}

			// ie7 must use absolute positioning in quirks mode and to account
			// for activex issues (when scrolling)
			var expr = setExpr
					&& (!$.boxModel || $('object,embed', full ? null : el).length > 0);
			if (ie6 || expr) {
				// give body 100% height
				if (full && opts.allowBodyStretch && $.boxModel)
					$('html,body').css('height', '100%');

				// fix ie6 issue when blocked element has a border width
				if ((ie6 || !$.boxModel) && !full) {
					var t = sz(el, 'borderTopWidth'), l = sz(el,
							'borderLeftWidth');
					var fixT = t ? '(0 - ' + t + ')' : 0;
					var fixL = l ? '(0 - ' + l + ')' : 0;
				}

				// simulate fixed position
				$
						.each(
								[ lyr1, lyr2, lyr3 ],
								function(i, o) {
									var s = o[0].style;
									s.position = 'absolute';
									if (i < 2) {
										full ? s
												.setExpression(
														'height',
														'Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.boxModel?0:'
																+ opts.quirksmodeOffsetHack
																+ ') + "px"')
												: s
														.setExpression(
																'height',
																'this.parentNode.offsetHeight + "px"');
										full ? s
												.setExpression(
														'width',
														'jQuery.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"')
												: s
														.setExpression('width',
																'this.parentNode.offsetWidth + "px"');
										if (fixL)
											s.setExpression('left', fixL);
										if (fixT)
											s.setExpression('top', fixT);
									} else if (opts.centerY) {
										if (full)
											s
													.setExpression(
															'top',
															'(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"');
										s.marginTop = 0;
									} else if (!opts.centerY && full) {
										var top = (opts.css && opts.css.top) ? parseInt(opts.css.top)
												: 0;
										var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '
												+ top + ') + "px"';
										s.setExpression('top', expression);
									}
								});
			}

			// show the message
			if (msg) {
				if (opts.theme)
					lyr3.find('.ui-widget-content').append(msg);
				else
					lyr3.append(msg);
				if (msg.jquery || msg.nodeType)
					$(msg).show();
			}

			if (($.browser.msie || opts.forceIframe) && opts.showOverlay)
				lyr1.show(); // opacity is zero
			if (opts.fadeIn) {
				var cb = opts.onBlock ? opts.onBlock : noOp;
				var cb1 = (opts.showOverlay && !msg) ? cb : noOp;
				var cb2 = msg ? cb : noOp;
				if (opts.showOverlay)
					lyr2._fadeIn(opts.fadeIn, cb1);
				if (msg)
					lyr3._fadeIn(opts.fadeIn, cb2);
			} else {
				if (opts.showOverlay)
					lyr2.show();
				if (msg)
					lyr3.show();
				if (opts.onBlock)
					opts.onBlock();
			}

			// bind key and mouse events
			bind(1, el, opts);

			if (full) {
				pageBlock = lyr3[0];
				pageBlockEls = $(':input:enabled:visible', pageBlock);
				if (opts.focusInput)
					setTimeout(focus, 20);
			} else
				center(lyr3[0], opts.centerX, opts.centerY);

			if (opts.timeout) {
				// auto-unblock
				var to = setTimeout(function() {
					full ? $.unblockUI(opts) : $(el).unblock(opts);
				}, opts.timeout);
				$(el).data('blockUI.timeout', to);
			}
		}
		;

		// remove the block
		function remove(el, opts) {
			var full = (el == window);
			var $el = $(el);
			var data = $el.data('blockUI.history');
			var to = $el.data('blockUI.timeout');
			if (to) {
				clearTimeout(to);
				$el.removeData('blockUI.timeout');
			}
			opts = $.extend({}, $.blockUI.defaults, opts || {});
			bind(0, el, opts); // unbind events

			if (opts.onUnblock === null) {
				opts.onUnblock = $el.data('blockUI.onUnblock');
				$el.removeData('blockUI.onUnblock');
			}

			var els;
			if (full) // crazy selector to handle odd field errors in ie6/7
				els = $('body').children().filter('.blockUI').add(
						'body > .blockUI');
			else
				els = $('.blockUI', el);

			if (full)
				pageBlock = pageBlockEls = null;

			if (opts.fadeOut) {
				els.fadeOut(opts.fadeOut);
				setTimeout(function() {
					reset(els, data, opts, el);
				}, opts.fadeOut);
			} else
				reset(els, data, opts, el);
		}
		;

		// move blocking element back into the DOM where it started
		function reset(els, data, opts, el) {
			els.each(function(i, o) {
				// remove via DOM calls so we don't lose event handlers
				if (this.parentNode)
					this.parentNode.removeChild(this);
			});

			if (data && data.el) {
				data.el.style.display = data.display;
				data.el.style.position = data.position;
				if (data.parent)
					data.parent.appendChild(data.el);
				$(el).removeData('blockUI.history');
			}

			if (typeof opts.onUnblock == 'function')
				opts.onUnblock(el, opts);
		}
		;

		// bind/unbind the handler
		function bind(b, el, opts) {
			var full = el == window, $el = $(el);

			// don't bother unbinding if there is nothing to unbind
			if (!b
					&& (full && !pageBlock || !full
							&& !$el.data('blockUI.isBlocked')))
				return;

			$el.data('blockUI.isBlocked', b);

			// don't bind events when overlay is not in use or if bindEvents is
			// false
			if (!opts.bindEvents || (b && !opts.showOverlay))
				return;

			// bind anchors and inputs for mouse and key events
			var events = 'mousedown mouseup keydown keypress';
			b ? $(document).bind(events, opts, handler) : $(document).unbind(
					events, handler);

			// former impl...
			// var $e = $('a,:input');
			// b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
		}
		;

		// event handler to suppress keyboard/mouse events when blocking
		function handler(e) {
			// allow tab navigation (conditionally)
			if (e.keyCode && e.keyCode == 9) {
				if (pageBlock && e.data.constrainTabKey) {
					var els = pageBlockEls;
					var fwd = !e.shiftKey && e.target === els[els.length - 1];
					var back = e.shiftKey && e.target === els[0];
					if (fwd || back) {
						setTimeout(function() {
							focus(back)
						}, 10);
						return false;
					}
				}
			}
			var opts = e.data;
			// allow events within the message content
			if ($(e.target).parents('div.' + opts.blockMsgClass).length > 0)
				return true;

			// allow events for content that is not being blocked
			return $(e.target).parents().children().filter('div.blockUI').length == 0;
		}
		;

		function focus(back) {
			if (!pageBlockEls)
				return;
			var e = pageBlockEls[back === true ? pageBlockEls.length - 1 : 0];
			if (e)
				e.focus();
		}
		;

		function center(el, x, y) {
			var p = el.parentNode, s = el.style;
			var l = ((p.offsetWidth - el.offsetWidth) / 2)
					- sz(p, 'borderLeftWidth');
			var t = ((p.offsetHeight - el.offsetHeight) / 2)
					- sz(p, 'borderTopWidth');
			if (x)
				s.left = l > 0 ? (l + 'px') : '0';
			if (y)
				s.top = t > 0 ? (t + 'px') : '0';
		}
		;

		function sz(el, p) {
			return parseInt($.css(el, p)) || 0;
		}
		;

	}
	;

	if (typeof define === 'function' && define.amd && define.amd.jQuery) {
		define([ 'jquery' ], setup);
	} else {
		setup(jQuery);
	}

})();
